﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using Twodi.Aspect.Args;
using Twodi.Arguments;
using Microsoft.Xna.Framework;

namespace Twodi.Aspect
{
    /// <summary>
    /// Aspecto responsavel por definir como o componente é.
    /// </summary>
    public abstract class AbstractAspect
    {
        /// <summary>
        /// Construtor padrão.
        /// </summary>
        public AbstractAspect()
        {
            AddEvents();
        }

        /// <summary>
        /// Adicionar eventos do aspecto.
        /// </summary>
        protected virtual void AddEvents()
        {

        }

        /// <summary>
        /// Evento invocado quando qualquer propriedade é alterada.
        /// </summary>
        public event EventHandler<PropertyChangedEventArgs> PropertyChanged;

        /// <summary>
        /// Invocar evento que informa que uma propriedade foi alterada.
        /// </summary>
        /// <param name="e"></param>
        private void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, e);
        }

        /// <summary>
        /// Invocar evento que informa que uma propriedade foi alterada.
        /// </summary>
        protected void OnPropertyChanged<T>(string propertyName, ref T oldValue, T newValue)
        {
            T bkOldValue = oldValue;
            oldValue = newValue;
            OnPropertyChanged(new PropertyChangedEventArgs(propertyName, bkOldValue, newValue));
            InvokePropertyChanged<T>(propertyName, bkOldValue, newValue);
        }

        protected void InvokePropertyChanged<T>(string propertyName, T oldValue, T newValue)
        {
            MethodInfo method = this.GetType().GetMethod("on" + propertyName + "Changed", BindingFlags.Instance | BindingFlags.NonPublic);

            if (method != null)
            {
                method.Invoke(this, new object[] { new DefaultChangedEventArgs<T>(oldValue, newValue) });
            }
            else
            {
                Console.WriteLine("Method 'on" + propertyName + "Changed' could not be found.");
            }
        }
    }
}
